<?php
namespace app\common\service;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Exception\GuzzleException;

class DoubanService{

    const API_SEARCH = 'https://api.douban.com/v2/movie/search';
    const API_DETAIL = 'https://api.douban.com/v2/movie/subject/';

    public  $errMsg = '';

    /**
     * @param $keyword
     * @param bool $async
     * @return bool|\GuzzleHttp\Promise\PromiseInterface|mixed|\Psr\Http\Message\ResponseInterface
     */
    public function search($keyword, $async = false) {
        $uri = self::API_SEARCH . '?q=' . $keyword;
        try {
            $response = $this->_request($uri, null, 'get', [], $async);
        } catch (GuzzleException $exception) {
            $this->errMsg = $exception->getMessage();
            return false;
        }

        if ($async) {
            return $response;
        }

        $body = $this->_response($response);
        return $body === false ? false : json_decode($body, true);
    }

    /**
     * @param $id
     * @param $async
     * @return bool|\GuzzleHttp\Promise\PromiseInterface|mixed|\Psr\Http\Message\ResponseInterface
     */
    public function getDetail($id, $async) {
        $uri = self::API_DETAIL . '/' . $id;
        try {
            $response = $this->_request($uri, null, 'get', [], $async);
        } catch (GuzzleException $exception) {
            $this->errMsg = $exception->getMessage();
            return false;
        }

        if ($async) {
            return $response;
        }

        $body = $this->_response($response);
        return $body === false ? false : json_decode((string) $body, true);
    }

    /**
     *
     * @param \Psr\Http\Message\ResponseInterface $response
     * @param bool $async
     * @return bool|mixed
     */
    private function _response($response) {
        if ($response->getStatusCode() !== 200) {
            $this->errMsg = $response->getReasonPhrase();
            return false;
        }

        return $response->getBody();
    }

    /**
     * @param $uri
     * @param null $body
     * @param string $method
     * @param array $headers
     * @param bool $async
     * @return \GuzzleHttp\Promise\PromiseInterface|mixed|\Psr\Http\Message\ResponseInterface
     * @throws GuzzleException
     */
    private function _request($uri, $body = null, $method = 'get', $headers = [], $async = false){
        $request = new Request($method, $uri, $headers, $body);
        $client = new Client(['timeout'  => 2.0,]);

        if ($async) {
            return $client->sendAsync($request);
        }
        return $client->send($request);
    }
}